/**  ------------------------------ 数据解析及命令参数转换js插件开发说明 --------------------------------------------------------------
 * 一、约定：
 * 1.每一个设备类型对应一个js插件文件，文件位置：相对于springboot的resources目录下面的路径(/js/plugin/<devtype>.js);
 * 2.js插件文件名为<devtype>.js，devtype为设备类型编号，如：haitong_ac_v1;
 * 3.js插件中包括一个上报数据解析方法和N个（N>=0）控制命令转换方法。
 * 
 * 二、设备上报业务数据（metedata）解析：
 * 1、方法名固定为:funcupdataparse. 
 * 2、入参固定为:JSParam，定义参见com.zte.claa.inficombo.csa.app.service.jsplugin.JSParam，包括如下方法：
 *	(2.1) getDevtypeid() -->获取当前设备类型ID；
 *	(2.2) getDeveui()    -->获取对应设备编号deveui；
 *	(2.3) getDevport()   -->获取设备上报的port，通常用不到；
 *	(2.4) getParas()     -->获取指标映射表：Map<String, Object>，对于上报数据,只有一个参数项：uppayload，value是byte[]，终端上报的原始码流.
 *	(2.5) getPara(pname) -->获取指定名称的参数，返回Object对象；
 *  (2.6) getAppeui()    -->获取对应的appeui参数；
 * 3、解析结果分为四种情况：metedata或alarmdata或Map<String, Object>或null。
 * (3.1)如果是无效数据，则返回null;
 * (3.2)如果是metedata，则解析结果为json字符串，形如：{"f1name":f1val, "f2name":f2val, ...}，其中fnname和当前设备类型的业务模型定义一致；
 * (3.3)如果是告警AlarmData，则返回的对象为AlarmData对象，该java类型的定义参见:com.zte.claa.inficombo.csa.app.model.redis.AlarmData.
 * (3.4)如果上报的数据中同时包括metedata和alarm或需要返还ackcmd，则返回Map<String, Object>，map中包括最多5个item，分别是：
 *      (3.4.1)key="metedata", value=metedata对应的json字符串，和3.2一致；
 *      (3.4.2)key="alarm", value=AlarmData对象，和3.3一致。
 *      (3.4.3)key="ackcmd",value=AppCmdWrapper对象，详见com.zte.claa.inficombo.csa.app.service.rptparse.AppCmdWrapper定义.
 *      (3.4.4)key="metedatalist", value=ArrayList<String>, 列表item=metedata对应的json字符串，和3.2一致；
 *      (3.4.5)key="alarmlist", value=ArrayList<AlarmData>, 列表item=AlarmData对象，和3.3一致。
 * 
 * 三、控制指令转换说明：
 * 1、每一个命令控制字对应一个function，function名称=控制字名称;
 * 2、每一个控制字对应的func入参统一为jsParam，定义同数据解析，其中getParas()方法获取命令控制参数：
 * 	  (2.4) getParas(), 返回值：Map<String, Object>，key=[P1,....,Pn],val=P1~Pn对应的参数值；
 *    (2.5) getPara(pname) -->获取指定名称的参数，返回Object对象；
 * 3、控制命令转换结果为byte[]。
 * 	 
 * 转换时可以使用的jdk8所提供的各类java对象，通常是如下List对象；JSONObject是json转换对象类，参照本例使用。 
 *  
 *  ---------------------------------------------------------------------------------------------------------------------
 *  常用java类型引用：
 *  var ByteBuffer = Java.type('java.nio.ByteBuffer');
 *  var List = Java.type('java.util.ArrayList');
 *  var Map = Java.type('java.util.HashMap');
 *  var String = Java.type('java.lang.String');
 *  var JSONObject = Java.type('org.json.JSONObject');
 *  var DecimalFormat = Java.type('java.text.DecimalFormat');
 *  
 *  java.text.DecimalFormat df = new java.text.DecimalFormat("#.00");  
 *  df.format(你要格式化的数字);
 *  
 * 		buf.get(); 		// read 1 byte
		buf.getShort(); // read 2 bytes
		buf.getInt(); 	// read 4 bytes
		buf.getLong(); 	// read 8 bytes
 */ 


var ByteBuffer = Java.type('java.nio.ByteBuffer');
var List = Java.type('java.util.ArrayList');
var Byte = Java.type('java.lang.Byte');
var JSONObject = Java.type('org.json.JSONObject');
var JSONArray = Java.type('org.json.JSONArray');
var Map = Java.type('java.util.HashMap');
var LogPrint = Java.type('com.zte.claa.inficombo.csa.app.service.rptparse.JsLogPrint');
var ConfDataRequest = Java.type('com.zte.claa.inficombo.csa.app.service.rptparse.ext.claa.ConfDataRequest');
var DevVersionUpdateLog = Java.type('com.zte.claa.inficombo.csa.app.model.version.DevVersionUpdateLog');
var LocRawData = Java.type('com.zte.claa.inficombo.csa.app.service.rptparse.LocRawData');
var AppCmdWrapper = Java.type('com.zte.claa.inficombo.csa.app.service.rptparse.AppCmdWrapper');
var AppCommand = Java.type('com.zte.claa.inficombo.csa.app.service.rptparse.AppCommand');
var AlarmData = Java.type('com.zte.claa.inficombo.csa.app.model.redis.AlarmData');


/*克拉蓝牙信标定位
 *上报数据解析方法,统一固定命名为:funcupdataparse
 *解析插件主流程
 *入参:JSParam
**/

function funcupdataparse(jsParam){
	var logger = new LogPrint();
	var bs = jsParam.getPara('uppayload');
	var buf = ByteBuffer.wrap(bs);	
	var msgtype = toHex(buf.get());
	
	logger.info("claa_btloc msg title is :" + getmsgtypename(msgtype));
		
	if ('10' == msgtype){		
		return processmsgtype_0x10(jsParam,buf);
		
	}else if('11' == msgtype){		
		return processmsgtype_0x11(jsParam,buf);
		
	}else if('31' == msgtype){
		return processmsgtype_0x31(jsParam,buf);
		
	}else if('34' == msgtype){
		return processmsgtype_0x34(jsParam,buf);
		
	}else if('37' == msgtype){
		return processmsgtype_0x37(jsParam,buf);
		
	}else if('20' == msgtype){
		return processmsgtype_0x20(jsParam,buf);
		
	}else{
		return null;		
	}	
}


/**
 * 获取消息类型名
 */
function getmsgtypename(msgtype){
	var logger = new LogPrint();
	logger.info("claa_btloc msg type is:" + msgtype);
	
	var ret = '';	
	switch(msgtype) {
    case '20':
    	ret = 'loc msg';
       break;
    case '10':
    	ret = 'config msg';
       break;
    case '11':
    	ret = 'config succ confirm msg';
    	break;
    case '31':
    	ret = 'ready upgrade ack msg';
    	break;
    case '34':
    	ret = 'cancel upgrade ack msg';
    	break;
    case '37':
    	ret = 'upgrade result msg';
    	break;
    default:
    	ret ='unknow msg';  
	} 
	return ret;	
}


//处理0x10消息
function processmsgtype_0x10(jsParam,buf){	
	var logger = new LogPrint();
	
	buf.getShort();
	buf.get();
	
	var confdata = new ConfDataRequest();
	confdata.setDeveui(jsParam.getDeveui());
	confdata.setAppeui(jsParam.getAppeui());
	confdata.setProjectid(jsParam.getProjectid());
	confdata.setCmdcode("SetBtLocParas");
		
	var mems_count = null;
	var battery_v = null;
	var boardid = null;
	var softver = "";
	var remarkdesc = "AddFlds:";
	
	while(buf.hasRemaining()){
		
		var tagbyte = buf.get() & 0x00FF;
		
		if(0x51 == tagbyte){
			mems_count = (buf.getInt() & 0x00FFFFFFFF);	
			remarkdesc = remarkdesc + ",mems_count:"+mems_count;
			confdata.setRemark(remarkdesc);
			
	    }else if(0x52 == tagbyte){
			battery_v = (buf.getShort() & 0x0000FFFF) / 100;
			battery_v = battery_v.toFixed(2);
			remarkdesc = remarkdesc+",battery:" + battery_v;
			confdata.setRemark(remarkdesc);	
			
		}else if(0x14 == tagbyte){
			buf.get();
			boardid = (buf.get() & 0x00FF);
			remarkdesc = remarkdesc+",boardid:"+boardid;
			confdata.setRemark(remarkdesc);
			
		}else if(0x12 == tagbyte){
			var verlen = buf.get() & 0x00FF;
			for(var idx=0; idx<verlen; idx++){
				var bytetemp = buf.get();
				softver = softver+String.fromCharCode(bytetemp);
			}
			confdata.setVersion(softver);
		}else{
			//终端后续的参数都会带L字段,遇到未定义的T,跳过L长度字节
			logger.info("claa_btloc : not supported tag, T:" + toHex(tagbyte));							
			var len = buf.get();
			for (var i = 0;i < len; i++){
				buf.get();
			}
		}
	}				
	return confdata;
}


//处理0x11消息
function processmsgtype_0x11(jsParam,buf){	
	var locrawdata = new LocRawData();
	locrawdata.setActived(1);
	return locrawdata;	
}

//处理0x31消息
function processmsgtype_0x31(jsParam,buf){	
	buf.getShort();
	buf.get();
	
	var devUpdataLog = new DevVersionUpdateLog();		
	devUpdataLog.setRetcode(1);
	devUpdataLog.setRetbitmap("");
	devUpdataLog.setRemark("Ready upgrade");
	return devUpdataLog;	
}

//处理0x34消息
function processmsgtype_0x34(jsParam,buf){
	buf.getShort();
	buf.get();
	
	var devUpdataLog = new DevVersionUpdateLog();		
	devUpdataLog.setRetcode(0);
	devUpdataLog.setRetbitmap("");
	devUpdataLog.setRemark("Cancel upgrade");
	return devUpdataLog;
}

//处理0x37消息
function processmsgtype_0x37(jsParam,buf){	
	buf.getShort();
	buf.get();
	
	var devUpdataLog = new DevVersionUpdateLog();	
	var upDataResult = 0;
	var resBitmap = "";
	var resReason = "";
	while(buf.hasRemaining()){		
		var tagbyte = buf.get() & 0x00FF;
		
		if(0x62 == tagbyte) {
			buf.get();			
			var upgradeResult =  buf.get() & 0x00FF;
			if(1 == upgradeResult){
				upDataResult = 3;
				resReason = "Upgrade is successfull."
			}else{
				upDataResult = 4;
				var reason =  buf.get() & 0x00FF;
				
				if(1 == reason){
					resReason = "Crc verification fail.";
				}else if(2 == reason){
					resReason = "File is incomplete.";
					for(var j = 0; j < 64; j++){
						resBitmap += toHex(buf.get() & 0x00FF);
					}						
				}else if(3 == reason){
					resReason = "Filesize is too large.";
				}
			}
	    }
	}
	devUpdataLog.setRetcode(upDataResult);
	devUpdataLog.setRetbitmap(resBitmap);
	devUpdataLog.setRemark(resReason);
	return devUpdataLog;
}

//获取0x20消息中的detail分项中的上行包序字段
function processmsgtype_0x20_getseqno(jsParam){
	var logger = new LogPrint();
	var detail = jsParam.getPara('detail');
	if(detail == null){
		return -1;
	}
	var seqno = -1;
	try{
		seqno = detail.get('app').get('seqno');
	}catch(err){
		logger.info("processmsgtype_0x20_getseqno error:" + err);		
	}
	return seqno;
}

//处理0x20消息中的detail分项
function processmsgtype_0x20_detail(jsParam){
	var logger = new LogPrint();
	var detail = jsParam.getPara('detail');
	logger.info("claa_btloc processmsgtype_0x20_detail detail:" + detail);
	if(detail == null){
		return null;
	}		
	var detailJson = new JSONObject();	
	var projectid = jsParam.getProjectid();
	detailJson.put("projectid", projectid);
	try{
		var seqno = detail.get('app').get('seqno');
		var gwnum = detail.get('app').get('gwnum');	
		if(gwnum == null || gwnum == 0){
			return null;
		}
		detailJson.put('seqno',seqno);		
		var gwrx = detail.get('app').get('gwrx');	
		if(gwrx == null || gwrx.length() == 0){
			return null;
		}	
		for(var i = 0 ; i < gwrx.length() ; i++){
			if(i > 7)break;	//最多存储8组gw信号

			var obj = gwrx.get(i);			
			var gw = obj.get('gweui');
			detailJson.put('gw' + i , gw);			
			var rssi = obj.get('rssic');
			detailJson.put('rssi' + i , rssi);			
			var snr = obj.get('lsnr');
			detailJson.put('snr' + i , snr);
		}
		logger.info("claa_btloc processmsgtype_0x20_detail :" + detailJson.toString());
		return detailJson;
	}catch(err){
		logger.info("processmsgtype_0x20_detail error:" + err);
		return null;
	}	
}



//处理0x20消息
function processmsgtype_0x20(jsParam,buf){		
	var logger = new LogPrint();
	
	buf.getShort();
	buf.get();
	
	var projectid = jsParam.getProjectid();
	var locjson = new JSONObject();	
	locjson.put("projectid", projectid);
	locjson.put("type", 50);//蓝牙终端定位标志
		
	var devpowerjson = new JSONObject();//终端电量信息	
	devpowerjson.put("projectid", projectid);
	var memsDetailjson = new JSONObject();//mems状态信息	
	var locrawdata = new LocRawData();//定位消息对象	
	var retMap = new Map();//返回map对象	
	var appwrapper = new AppCmdWrapper();//应答包对象	
	var alarmList = new List();//报警列表	
	var sosAlarm  = null;//sos报警对象
		
	var mems_count = null;
	var cur_volt = null;
	var cur_percent = null;	
	var mems_shock_flag = null;	
	var sos = null;
	var press = null;
	var temp = null;
	var humd = null;
				
	var safetyhelmetstatus = null;
	var safetyhelmetlength = null;
	
	var dwrssi = null;//下行rssi
	var dwsnr = null;//下行snr	
	var seqno = null;//下行包序
				
	while(buf.hasRemaining()){			
		var tagbyte = buf.get() & 0x00FF;
		
		if(0x51 == tagbyte) {
			mems_count = (buf.getInt() & 0x00FFFFFFFF);	
			locjson.put("mems_count", mems_count);
			
	    }else if(0x82 == tagbyte){
			var btnum = (buf.get() & 0x00FF) / 7;
			logger.info("claa_btloc carry beacon number :" + btnum);
			for(var idx = 0; idx < btnum; idx++){
				var dbyte = buf.get() & 0x00FF;
				var gwstr = toHex(dbyte);				
				dbyte = buf.get() & 0x00FF;
				gwstr = toHex(dbyte) + gwstr;				
				dbyte = buf.get() & 0x00FF;
				gwstr = toHex(dbyte) + gwstr;				
				dbyte = buf.get() & 0x00FF;
				gwstr = toHex(dbyte) + gwstr;
				gwstr = "c1aa" + gwstr;					
				var prix = idx + 1;
				var name = "gw"+ prix;
				locjson.put(name, gwstr);				
				
				var btlabelpowerjson = new JSONObject();//构造标签电压等级对象,标签电量信息:{label:c1aa00001,curvollevel:1}		
				btlabelpowerjson.put("projectid", projectid);
				btlabelpowerjson.put("labeleui", gwstr);
				
				if(idx < 5){
					memsDetailjson.put(name, gwstr);	
				}								
				name = "rssi" + prix;
				var rssival =  buf.get() & 0x00FF;
				rssival = rssival.toFixed(8);
				rssival = -1 * rssival;
				locjson.put(name, rssival);
				if(idx < 5){
					memsDetailjson.put(name, rssival);
				}								
				var mcwbyte =  buf.get() & 0x00FF;				
				var voltlevel = (mcwbyte >> 2) & 0x03;	
				
				btlabelpowerjson.put("curvoltage", voltlevel);
				logger.info("Js parsed claa_btloc btlabelpowerjson:" + btlabelpowerjson.toString());				
				//蓝牙标签电压等级信息添加到队列里
				locrawdata.addLabelPowerData(btlabelpowerjson.toString());	
				//读取最后一个字节
				var rtcsbyte =  buf.get() & 0x00FF;
			}
			
		}else if(0x52 == tagbyte){			
			cur_volt = (buf.getShort() & 0x0000FFFF) / 100;
			cur_volt = cur_volt.toFixed(2);		
			cur_percent = get_cur_percent(cur_volt);
			locjson.put("cur_volt", cur_volt);	
			locjson.put("cur_percent", cur_percent);
			
			devpowerjson.put("curvoltage", cur_volt);
			
		}else if(0x5a == tagbyte){
			buf.get();			
			var sum1 = buf.get() & 0x00FF;
			var sum2 = buf.get() & 0x00FF;
			var sum3 = buf.get() & 0x00FF;
			var sum = sum1 * 256 * 256 + sum2 * 256 + sum3;
			
			devpowerjson.put("powerconsum", sum);
			
		}else if(0x55 == tagbyte){
			buf.get();
			var tb = buf.get();	
			
			var b0multishake = (tb & 0x0001);
			var b1curshake = (tb>>1 & 0x0001);
			var b2angle= (tb>>2 & 0x0001);
			var b3btack= (tb>>3 & 0x0001);			
			var b4btopen= (tb>>4 & 0x0001);
			var b5gpsopen= (tb>>5 & 0x0001);
			var b6linkcheck= (tb>>6 & 0x0001);
			var b7gwsync= (tb>>7 & 0x0001);
					
			memsDetailjson.put("b0multishake",b0multishake);
			memsDetailjson.put("b1curshake",b1curshake);
			memsDetailjson.put("b2angle", b2angle);
			memsDetailjson.put("b3btack", b3btack);
			memsDetailjson.put("b4btopen", b4btopen);
			memsDetailjson.put("b5gpsopen", b5gpsopen);
			memsDetailjson.put("b6linkcheck", b6linkcheck);
			memsDetailjson.put("b7gwsync", b7gwsync);
			
			mems_shock_flag = b0multishake;
			locjson.put("mems_shock_flag", mems_shock_flag);
			
		}else if(0x19 == tagbyte){
			buf.get();
			sos = (buf.get() & 0x00FF);
			locjson.put("sos", sos);
			buildDevAckCmd(jsParam, appwrapper);
			retMap.put("ackcmd",appwrapper);
			sosAlarm = GetAlarmDataInit(jsParam);
			
			if(sos == 1){
				sosAlarm.setAlarmcode("80009-1");
				sosAlarm.setAlarmTimeWithCurTime();
				sosAlarm.setTitle('sos');		
			}else if(sos == 0){
				sosAlarm.setAlarmcode("80009-1");
				sosAlarm.setTypeflag(0);
				sosAlarm.setClearTimeWithCurTime();
				sosAlarm.setTitle('No sos');			
			}else{
				sosAlarm.setAlarmcode("2");
				sosAlarm.setTypeflag(2);
				sosAlarm.setAlarmlevel(0);
				sosAlarm.setAlarmTimeWithCurTime();
				sosAlarm.setTitle('Other message sos:' + sos);
			}
			alarmList.add(sosAlarm);	
			
		}else if(0x4a == tagbyte){
			buf.get();
			var locsuctime = (buf.getShort() & 0x00FFFF);
			locjson.put("locsuctime", locsuctime);
			
		}else if(0x57 == tagbyte){
			buf.get();
			press = (buf.getInt() & 0x00FFFFFFFF);
			locjson.put("press", press);
			
		}else if(0x75 == tagbyte) {
			buf.get();
			temp = buf.getShort() / 100.0;	
			temp = temp.toFixed(2);	
			locjson.put("temp", temp);
			
	    }else if(0x76 == tagbyte){
			buf.get();
			humd = (buf.getShort() & 0x00FFFF) / 100.0;		
			humd = humd.toFixed(2);
			if(humd > 100.00){
				humd = 100.00;
			}
			locjson.put("humd", humd);	
			
		}else if(0x7e == tagbyte){		
			buf.get();
			safetyhelmetstatus = (buf.get() & 0x00FF);		
			locjson.put("safetyhelmetstatus", safetyhelmetstatus);	
			
		}else if(0x7f == tagbyte){
			buf.get();
			safetyhelmetlength = (buf.getShort() & 0x00FFFF);		
			locjson.put("safetyhelmetlength", safetyhelmetlength);	
			
		}else if(0x1e == tagbyte){
			buf.get();
			var slopeflag = (buf.get() & 0x01);
			var alarmslope = GetAlarmDataInit(jsParam);
			if(slopeflag == 1){
				alarmslope.setAlarmcode("80010-1");
				alarmslope.setAlarmTimeWithCurTime();
				alarmslope.setTitle('倾斜告警');	
				
			}else{
				alarmslope.setAlarmcode("80010-1");
				// typeflag=0表示告警恢复.
				alarmslope.setTypeflag(0);
				alarmslope.setClearTimeWithCurTime();
				alarmslope.setTitle('倾斜恢复');		
			}
			alarmList.add(alarmslope);
			
		}else if(0x3f == tagbyte){
			buf.get();
			dwrssi = (buf.get() & 0x00FF);	
			dwsnr = (buf.get() & 0x00FF);
		}else{
			logger.info("claa_btloc : not supported tag, T:" + toHex(tagbyte));							
			var len = buf.get();
			for (var i = 0;i < len; i++){
				buf.get();
			}
		}		
	}
	
	//lcs进程解析参数(否则会报错!!!!,所以必须组装好这些参数){cur_volt,mems_count,mems_shock_flag,sos,press,cur_percent}
	if (cur_volt == null){
		locjson.put("cur_volt", 0);
	}
	if (cur_percent == null){
		locjson.put("cur_percent", 0);
	}
	if(mems_count == null ){
		locjson.put("mems_count", 0);
	}
	if(mems_shock_flag == null ){
		locjson.put("mems_shock_flag", 0);
	}
	if(sos == null ){
		locjson.put("sos", 0);
	}
	if(press == null ){
		locjson.put("press", 0);
	}
	if(temp == null ){
		locjson.put("temp", 0);
	}
	if(humd == null ){
		locjson.put("humd", 0);
	}
	
	//解析detail中的上行包序号
	seqno = processmsgtype_0x20_getseqno(jsParam);
	locjson.put("seqno", seqno);			
	//解析detail数据中的网管lora信号强度
	var detailRet = processmsgtype_0x20_detail(jsParam);	
	if(detailRet != null){
		if(dwrssi != null){
			detailRet.put('dwrssi',dwrssi * -1);//前一包的下行rssi
		}
		if(dwsnr != null){
			detailRet.put('dwsnr',dwsnr);//前一包的下行snr
		}
		locrawdata.addDeveuiGwStateData(detailRet.toString());
		logger.info("Js parsed claa_btloc devgwstate:" + detailRet.toString());
	}

	locrawdata.addBtBeaconData(locjson.toString());
	logger.info("Js parsed claa_btloc metadata:" + locjson.toString());
		
	locrawdata.addDevPowerData(devpowerjson.toString());
	logger.info("Js parsed claa_btloc devpowerjson:" + devpowerjson.toString());
		
	locrawdata.addMemsStateJsonData(memsDetailjson.toString());
	logger.info("Js parsed claa_btloc memsDetailjson:" + memsDetailjson.toString());
			
	retMap.put('locrawdata', locrawdata);	
	retMap.put('alarmlist', alarmList);	
	return retMap;		
}


//计算电量,终端给的计算公式,硬编码搞一下(只有纯gps需要插件处理,蓝牙融合终端的电压段总给计算后插入record表中)
function get_cur_percent(power){
	if(power == null)
		power = 0;
	
	var low = 3.4;
	var high = 4.2;
	var interval = (high - low) / 10;
	
	if (power <= low) {
		return 	10;
	}	
	if (power >= high) {
		return 	100;
	}
	return (Math.floor((power - low) / interval) + 1) * 10;		
}

//初始化报警对象
function GetAlarmDataInit(jsParam){
	var alarm = new AlarmData();
	alarm.setDeveui(jsParam.getDeveui());
	alarm.setDevtype(jsParam.getDevtypeid());
	alarm.setProjectid(jsParam.getProjectid());
	alarm.setTypeflag(1);
	alarm.setAlarmlevel(1);
	return alarm;
}

//构造下行回复包
function buildDevAckCmd(jsParam, appwrapper){
	appwrapper.setAppeui(jsParam.getAppeui());
	appwrapper.setDeveui(jsParam.getDeveui());
	appwrapper.setDevtypeid(jsParam.getDevtypeid());
	appwrapper.setConfirm(false);
	appwrapper.setPort(jsParam.getDevport());
	
	var appcmd =  new AppCommand();
	appcmd.setCmd("ReplySoSReportMsg");
	appcmd.appendPara("isclean",0);
	appwrapper.setPayload(appcmd);
	return;
}



function ReplySoSReportMsg(jsParam){
	var logger = new LogPrint();
	var cmdParaMap = jsParam.getParas();
	var isclean = cmdParaMap.get("isclean");
	var head = [];
	var data = [];
	var ret = [];
	var datalen = 0;
	var databyte = new Byte(0);
	
	head.push(0x10);
	head.push(0x00);
	head.push(0x0a);
	
	if(isclean == 0 || isclean == 1){
		data.push(0x19);
		data.push(0x01);
        databyte = isclean & 0xFF;
        data.push(databyte);
        datalen += 3;
	}else{
		return null;
	}
	
	head.push(datalen);	
	ret = head.concat(data);	
	return Java.to(ret, "byte[]");
}



// 下发配置信息
function SetBtLocParas(jsParam){
	var cmdParaMap = jsParam.getParas();
	var isactived = cmdParaMap.get("isactived");
	var devtype = cmdParaMap.get("devtype");
	var dr = cmdParaMap.get("dr");
	var stepreset = cmdParaMap.get("stepreset");
	var beaconinterval = cmdParaMap.get("beaconinterval");
	var dotopinterval = cmdParaMap.get("dotopinterval");
	var dotlocinterval = cmdParaMap.get("dotlocinterval");
	var ismemsopened = cmdParaMap.get("ismemsopened");
	var memsthrd = cmdParaMap.get("memsthrd");
	var isbtopened = cmdParaMap.get("isbtopened");
	var isweekendworked = cmdParaMap.get("isweekendworked");
	var starttime = cmdParaMap.get("starttime");
	var endtime = cmdParaMap.get("endtime");
	var isrptedbtdata = cmdParaMap.get("isrptedbtdata");
	var restartchecktime = cmdParaMap.get("restartchecktime");// 重启检测时长
	var btbeaconupnum = cmdParaMap.get("btbeaconupnum");// 蓝牙信标上传最优个数
	var offlinecheckcycle = cmdParaMap.get("offlinecheckcycle");// 离网检测周期
	var memskeepcyclenum = cmdParaMap.get("memskeepcyclenum");// MEMS运动保持周期个数
	var forcetdma = cmdParaMap.get("forcetdma");// 强制指定终端支持TDMA功能, 0：不支持TDMA,1：支持TDMA
	var closegpsafterbt = cmdParaMap.get("closegpsafterbt");// 蓝牙定位成功是否关闭GPS,0：不关闭GPS,1：关闭GPS
	var offlinechecktime = cmdParaMap.get("offlinechecktime");// 离网检测时长
	var btlocmod = cmdParaMap.get("btlocmod");// 蓝牙定位模式
	var searchbtbeacon = cmdParaMap.get("searchbtbeacon");// 搜索蓝牙信标类型
	var opendebug = cmdParaMap.get("opendebug");// 调试信息是否上传
	var heartbeatcycle = cmdParaMap.get("heartbeatcycle");	// 心跳周期
	var ispressopened = cmdParaMap.get("ispressopened");	
	var istemphumdopened = cmdParaMap.get("istemphumdopened");		
	var fastresumecheckcircle = cmdParaMap.get("fastresumecheckcircle");// 快速恢复网络检测周期
	var slowresumecheckcircle = cmdParaMap.get("slowresumecheckcircle");// 慢速恢复网络检测周期
	/* 蜂鸣器与红外测距begin */
	var activebuzzer = cmdParaMap.get("activebuzzer");
	var buzzerinterval = cmdParaMap.get("buzzerinterval");
	var buzzertime = cmdParaMap.get("buzzertime");
	var dangerareaactive = cmdParaMap.get("dangerareaactive");
	var dangerareaalarminterval = cmdParaMap.get("dangerareaalarminterval");
	var dangerareaalarmtime = cmdParaMap.get("dangerareaalarmtime");
	var activeinfrareddistance = cmdParaMap.get("activeinfrareddistance");
	var specialbeaconflag = cmdParaMap.get("specialbeaconflag");
	var safetyhelmettestinterval = cmdParaMap.get("safetyhelmettestinterval");
	var safetyhelmetthreshold = cmdParaMap.get("safetyhelmetthreshold");
	/* 蜂鸣器与红外测距end */			
	var gwbeaconsf = cmdParaMap.get("gwbeaconsf");// 网关BEACON的扩频因子
	var gwbeaconchannel = cmdParaMap.get("gwbeaconchannel");// 网关BEACON的信道
	var btbeaconrssi = cmdParaMap.get("btbeaconrssi");// 蓝牙信标rssi阈值
	var btlocsuccthreshold = cmdParaMap.get("btlocsuccthreshold");// 判定蓝牙定位成功与否阈值
	
	var gwbeaconrealcycle = cmdParaMap.get("gwbeaconrealcycle");//网关BEACON实际发送周期	
	var tdmaworkmode = cmdParaMap.get("tdmaworkmode");//终端TDMA方式中的工作模式
	
	var normalopendownwindowtime = cmdParaMap.get("normalopendownwindowtime");//正常业务开启下行窗口时间
		
	var logger = new LogPrint();		
	var head = [];
	var data = [];
	var ret = [];
	var datalen = 0;
	
	head.push(0x10);
	head.push(0x00);
	head.push(0x0a);
		
	if(isactived == 0 || isactived == 1){
		data.push(0x10);
        var isactivedByte = new Byte(0);
        isactivedByte = isactived & 0xFF;
        data.push(isactivedByte);
        datalen += 2;
	}
	
	if(devtype == 50){
		data.push(0x01);
		data.push(0x01);
		data.push(0x32);			
		datalen += 3;
	}
		
    if(dr >= 0 && dr <= 5){
		data.push(0x26);
        var drByte = new Byte(0);
        drByte = dr & 0xFF;
        data.push(drByte);
        datalen += 2; 	
    }
   
    if(stepreset == 0 || stepreset == 1){
		data.push(0x50);
        var stepresetByte = new Byte(0);
        stepresetByte = stepreset & 0xFF;
        data.push(stepresetByte);
        datalen += 2; 	
    }
              
	if(dotopinterval != null){
		data.push(0x80);
		data.push(0x03);
		var dotopinterByte = new Byte(0); 
		dotopinterByte = dotopinterval>>16 & 0xFF;
		data.push(dotopinterByte); 	
		dotopinterByte = dotopinterval>>8 & 0xFF;
		data.push(dotopinterByte); 
		dotopinterByte = dotopinterval & 0xFF;
		data.push(dotopinterByte); 
		datalen += 5;		
	}
	
	if(dotlocinterval != null){
		data.push(0x81);
		data.push(0x03);
		var dotlocinterByte = new Byte(0); 
		dotlocinterByte = dotlocinterval>>16 & 0xFF;
		data.push(dotlocinterByte); 	
		dotlocinterByte = dotlocinterval>>8 & 0xFF;
		data.push(dotlocinterByte); 
		dotlocinterByte = dotlocinterval & 0xFF;
		data.push(dotlocinterByte); 
		datalen += 5;		
	}

	if(beaconinterval != null){
		data.push(0x35);
		data.push(0x01);
		var scanInterByte = new Byte(0); 
		scanInterByte = beaconinterval & 0xFF;
		data.push(scanInterByte); 
		datalen += 3;
	}
	
	if(ismemsopened != null){
		data.push(0x53);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = ismemsopened & 0xFF;
		data.push(databyte); 
		datalen += 3;
	}
		
	if(memsthrd != null){
		data.push(0x54);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = memsthrd & 0xFF;
		data.push(databyte); 
		datalen += 3;
	}
		
	if(isbtopened != null){
		data.push(0x83);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = isbtopened & 0xFF;
		data.push(databyte); 
		datalen += 3;
	}
			
	if(isweekendworked != null){
		data.push(0x46);
		data.push(0x01);
		var databyte = new Byte(0); 
		isweekendworked = ""+isweekendworked+"";
		var arr = isweekendworked.split(",");
		
		for(var idx=0; idx<arr.length; idx++){
			var daystr = arr[idx].trim();
			if(daystr == "1"){
				databyte = databyte | 0x01;
			}
			else if(daystr == "2"){
				databyte = databyte | 0x02;
			}
			else if(daystr == "3"){
				databyte = databyte | 0x04;
			}
			else if(daystr == "4"){
				databyte = databyte | 0x08;
			}
			else if(daystr == "5"){
				databyte = databyte | 0x10;
			}	
			else if(daystr == "6"){
				databyte = databyte | 0x20;
			}	
			else if(daystr == "7"){
				databyte = databyte | 0x40;
			}	
			else {
				;
			}			
		}
		data.push(databyte);
		datalen += 3;		
	}else{
		data.push(0x46);
		data.push(0x01);
		var databyte = new Byte(0x7F); 
		data.push(databyte);
		datalen += 3;
	}
	
	if(ispressopened != null && (ispressopened == 0 || ispressopened == 1)){
		data.push(0x56);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = ispressopened & 0xFF;
		data.push(databyte); 
		datalen += 3;
	}	
	
	if(istemphumdopened != null && (istemphumdopened == 0 || istemphumdopened == 1)){
		data.push(0x58);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = istemphumdopened & 0xFF;
		data.push(databyte); 
		datalen += 3;
	}
		
	if(isrptedbtdata != null && (isrptedbtdata == 0 || isrptedbtdata == 1) ){
		data.push(0x84);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = isrptedbtdata & 0xFF;
		data.push(databyte); 	
		datalen += 3;
	}
	
	if(fastresumecheckcircle != null){
		data.push(0x2e);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = fastresumecheckcircle & 0xFF;
		data.push(databyte); 
		datalen += 3;
	}
	
	if(slowresumecheckcircle != null){
		data.push(0x2f);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = slowresumecheckcircle & 0xFF;
		data.push(databyte); 
		datalen += 3;
	}
	
	if(restartchecktime != null ){
		data.push(0x18);
		data.push(0x02);
		var databyte = new Byte(0); 
		databyte = restartchecktime>>8 & 0xFF;
		data.push(databyte); 
		databyte = restartchecktime & 0xFF;
		data.push(databyte); 
		datalen += 4;		
	}

	if(btbeaconupnum != null ){
		data.push(0x28);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = btbeaconupnum & 0xFF;
		data.push(databyte); 
		datalen += 3;		
	}
	
	if(offlinecheckcycle != null ){
		data.push(0x29);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = offlinecheckcycle & 0xFF;
		data.push(databyte); 
		datalen += 3;		
	}
	
	if(memskeepcyclenum != null ){
		data.push(0x2a);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = memskeepcyclenum & 0xFF;
		data.push(databyte); 
		datalen += 3;		
	}
	
	if(forcetdma != null ){
		data.push(0x2b);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = forcetdma & 0xFF;
		data.push(databyte); 
		datalen += 3;		
	}
	
	if(closegpsafterbt != null ){
		data.push(0x2c);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = closegpsafterbt & 0xFF;
		data.push(databyte); 
		datalen += 3;		
	}
	
	if(offlinechecktime != null ){
		data.push(0x2d);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = offlinechecktime & 0xFF;
		data.push(databyte); 
		datalen += 3;		
	}
	
	if(btlocmod != null ){
		data.push(0x86);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = btlocmod & 0xFF;
		data.push(databyte); 
		datalen += 3;		
	}
	
	if(searchbtbeacon != null ){
		data.push(0x87);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = searchbtbeacon & 0xFF;
		data.push(databyte); 
		datalen += 3;		
	}
	
	if(opendebug == 0 || opendebug == 1){
		data.push(0x15);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = opendebug & 0x01;
		data.push(databyte); 
		datalen += 3;
	}	
	
	if(heartbeatcycle != null){
		data.push(0x71);
		data.push(0x03);
		var databyte = new Byte(0); 
		databyte = heartbeatcycle >> 16 & 0xFF;
		data.push(databyte); 
		databyte = heartbeatcycle >> 8 & 0xFF;
		data.push(databyte); 
		databyte = heartbeatcycle & 0xFF;
		data.push(databyte);
		datalen += 5;
	}	
	
	if(starttime != null && endtime != null && endtime > starttime){
		data.push(0x45);
		data.push(0x02);
		var databyte = new Byte(0); 
		databyte = starttime & 0xFF;
		data.push(databyte); 
		databyte = endtime & 0xFF;
		data.push(databyte); 		
		datalen += 4;
	}
		
	if(activebuzzer != null){
		data.push(0x77);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = activebuzzer & 0xFF;
		data.push(databyte); 
		datalen += 3;						
	}
	
	if(buzzerinterval != null){		
		data.push(0x78);
		data.push(0x02);
		var databyte = new Byte(0); 
		databyte = buzzerinterval>>8 & 0xFF;
		data.push(databyte); 
		databyte = buzzerinterval & 0xFF;
		data.push(databyte); 
		datalen += 4;			
	}
	
	if(buzzertime != null){		
		data.push(0x79);
		data.push(0x02);
		var databyte = new Byte(0); 
		databyte = buzzertime>>8 & 0xFF;
		data.push(databyte); 
		databyte = buzzertime & 0xFF;
		data.push(databyte); 
		datalen += 4;			
	}
	
	if(dangerareaactive != null){		
		data.push(0x7a);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = dangerareaactive & 0xFF;
		data.push(databyte); 
		datalen += 3;			
	}
	
	if(dangerareaalarminterval != null){		
		data.push(0x7b);
		data.push(0x02);
		var databyte = new Byte(0); 
		databyte = dangerareaalarminterval>>8 & 0xFF;
		data.push(databyte); 
		databyte = dangerareaalarminterval & 0xFF;
		data.push(databyte); 
		datalen += 4;			
	}
	
	if(dangerareaalarmtime != null){		
		data.push(0x7c);
		data.push(0x02);
		var databyte = new Byte(0); 
		databyte = dangerareaalarmtime>>8 & 0xFF;
		data.push(databyte); 
		databyte = dangerareaalarmtime & 0xFF;
		data.push(databyte); 
		datalen += 4;			
	}
	
	if(activeinfrareddistance != null){		
		data.push(0x7d);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = activeinfrareddistance & 0xFF;
		data.push(databyte); 
		datalen += 3;			
	}
	
	if(specialbeaconflag != null){		
		data.push(0x88);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = specialbeaconflag & 0xFF;
		data.push(databyte); 
		datalen += 3;			
	}
	
	if(safetyhelmetthreshold != null){		
		data.push(0x89);
		data.push(0x02);
		var databyte = new Byte(0); 
		databyte = safetyhelmetthreshold >> 8 & 0xFF;
		data.push(databyte); 
		databyte = safetyhelmetthreshold & 0xFF;
		data.push(databyte); 
		datalen += 4;			
	}
	
	if(normalopendownwindowtime != null){		
		data.push(0x1d);
		data.push(0x02);
		var databyte = new Byte(0); 
		databyte = normalopendownwindowtime >> 8 & 0xFF;
		data.push(databyte); 
		databyte = normalopendownwindowtime & 0xFF;
		data.push(databyte); 
		datalen += 4;			
	}
	
	if(safetyhelmettestinterval != null){		
		data.push(0x8a);
		data.push(0x02);
		var databyte = new Byte(0); 
		databyte = safetyhelmettestinterval >> 8 & 0xFF;
		data.push(databyte); 
		databyte = safetyhelmettestinterval & 0xFF;
		data.push(databyte); 
		datalen += 4;			
	}
	
	if(gwbeaconsf != null){		
		data.push(0x1b);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = gwbeaconsf & 0xFF;
		data.push(databyte); 
		datalen += 3;			
	}
	
	if(gwbeaconchannel != null){		
		data.push(0x1c);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = gwbeaconchannel & 0xFF;
		data.push(databyte); 
		datalen += 3;			
	}

	if(btbeaconrssi != null){
		data.push(0x3b);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = btbeaconrssi & 0xFF;
		data.push(databyte); 
		datalen += 3;
	}
	
	if(btlocsuccthreshold != null){
		data.push(0x36);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = btlocsuccthreshold & 0xFF;
		data.push(databyte); 
		datalen += 3;
	}
	
	if(gwbeaconrealcycle != null){
		data.push(0x4e);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = gwbeaconrealcycle & 0xFF;
		data.push(databyte); 
		datalen += 3;
	}
	
	if(tdmaworkmode != null){
		data.push(0x4f);
		data.push(0x01);
		var databyte = new Byte(0); 
		databyte = tdmaworkmode & 0xFF;
		data.push(databyte); 
		datalen += 3;
	}
	
	head.push(datalen);
	ret = head.concat(data);	
	return Java.to(ret, "byte[]");		
}



function DevVerUpdPrepare(jsParam){
	var cmdParaMap = jsParam.getParas();
	var keyend = cmdParaMap.get("keyend");
	var bcatfreq = cmdParaMap.get("bcatfreq");
	var dr = cmdParaMap.get("dr");
	var starttime = cmdParaMap.get("starttime");
	var runtime = cmdParaMap.get("runtime");
	var filesize = cmdParaMap.get("filesize");
	var blocknum = cmdParaMap.get("blocknum");
	var filename = cmdParaMap.get("filename");
	var crc32 = cmdParaMap.get("crc32");
	
	var logger = new LogPrint();
	var head = [];
	var confdata = [];
	var ret = [];
	var confdatalen = 0;
	var databyte = new Byte(0);
	
	head.push(0x30);
	head.push(0x00);
	head.push(0x0a);
	
	confdata.push(0x60);
	confdatalen += 1;
	
	logger.info("Js paras keyend:" + keyend);
	if(keyend != null){      
		databyte = keyend & 0xFF;
		confdata.push(databyte);
		confdatalen += 1;		
	}else{
		return null;
	}	
	
	logger.info("Js paras bcatfreq:" + bcatfreq);
	if(bcatfreq != null){   
		bcatfreq = bcatfreq*10;  //终端频率单位100KHZ
		bcatfreq = bcatfreq.toFixed(0);
		databyte = bcatfreq>>8 & 0xFF;
		confdata.push(databyte); 
		databyte = bcatfreq & 0xFF;
		confdata.push(databyte); 
		confdatalen += 2;		
	}else{
		return null;
	}	
	
	logger.info("Js paras dr:" + dr);
	if(dr != null){        
		dr = dr.toFixed(0);
		databyte = dr & 0xFF;
		confdata.push(databyte); 
		confdatalen += 1;		
	}else{
		return null;
	}	
	
	logger.info("Js paras starttime:" + starttime);
	if(starttime != null){   
		starttime = starttime.toFixed(0);
		databyte = starttime>>24 & 0xFF;
		confdata.push(databyte); 		
		databyte = starttime>>16 & 0xFF;
		confdata.push(databyte); 		
		databyte = starttime>>8 & 0xFF;
		confdata.push(databyte); 
		databyte = starttime & 0xFF;
		confdata.push(databyte); 
		confdatalen += 4;		
	}else{
		return null;
	}
	
	logger.info("Js paras runtime:" + runtime);
	if(runtime != null){   
		runtime = runtime.toFixed(0);
		databyte = runtime & 0xFF;
		confdata.push(databyte); 	
		confdatalen += 1;		
	}else{
		return null;
	}
	
	logger.info("Js paras filesize:" + filesize);
	if(filesize != null){   
		filesize = filesize.toFixed(0);		
		databyte = filesize>>16 & 0xFF;
		confdata.push(databyte); 		
		databyte = filesize>>8 & 0xFF;
		confdata.push(databyte); 
		databyte = filesize & 0xFF;
		confdata.push(databyte); 
		confdatalen += 3;		
	}else{
		return null;
	}
	
	logger.info("Js paras blocknum:" + blocknum);
	if(blocknum != null){   
		blocknum = blocknum.toFixed(0);				
		databyte = blocknum>>8 & 0xFF;
		confdata.push(databyte); 
		databyte = blocknum & 0xFF;
		confdata.push(databyte); 
		confdatalen += 2;		
	}else{
		return null;
	}
	
	logger.info("Js paras filename:" + filename);
	if(filename != null){   
		if(filename.length > 16){
			return null;
		}
		
		for(var i=0; i<16;i++){
			if(i<filename.length){
		        var str = filename.charAt(i);
		        var charcode= str.charCodeAt();
				databyte = charcode & 0xFF;
				confdata.push(databyte); 				
			}else{
				confdata.push(0x00); 
			}
		}
		confdatalen += 16;		
	}else{
		return null;
	}	
	
	logger.info("Js paras crc32:" + crc32);
	confdata.push(0x64);	
	confdatalen += 1;
	if(crc32 != null){   
		crc32 = crc32.toFixed(0);
		confdata.push(0x02);
		databyte = crc32>>8 & 0xFF;		
		confdata.push(databyte); 
		databyte = crc32 & 0xFF;
		confdata.push(databyte); 
		confdatalen += 3;
	}else{
		return null;
	}
	
	head.push(confdatalen);	
	ret = head.concat(confdata);	
	return Java.to(ret, "byte[]");	
}



function DevVerUpdCancel(jsParam){
	var cmdParaMap = jsParam.getParas();
	var logger = new LogPrint();
	var ret = [];
	
	ret.push(0x33);
	ret.push(0x00);
	ret.push(0x0a);
	ret.push(0x00);	
	return Java.to(confdata, "byte[]");
}



function DevVerBlockSent(jsParam){
	var cmdParaMap = jsParam.getParas();
	var seqno = cmdParaMap.get("seqno");
	var blockdata = cmdParaMap.get("blockdata");
	
	var logger = new LogPrint();
	var head = [];
	var confdata = [];
	var ret = [];
	var confdatalen = 0;
	var databyte = new Byte(0);
	
	head.push(0x35);
	head.push(0x00);
	head.push(0x0a);
	
	logger.info("Js paras seqno:" + seqno);
	if(seqno != null){   
		confdata.push(0x61);
		databyte = seqno>>8 & 0xFF;
		confdata.push(databyte); 
		databyte = seqno & 0xFF;
		confdata.push(databyte); 
		confdatalen += 3;
	}
	else{
		return null;
	}	
	
	if(blockdata != null){   
		var blocklen = blockdata.length;
		var byteslen = blocklen/2;
		if(blocklen%2 != 0){
			return null;
		}
		confdata.push(0x63);
		confdata.push(byteslen);
		confdatalen += 2;
		
		for(var i=0; i<byteslen;i++){
			var bytestr = blockdata.substring(i*2,2*i+2)
			var databyte = parseInt(bytestr,16);
			confdata.push(databyte); 
			confdatalen += 1;
		}
	}else{
		return null;
	}	
	
	head.push(confdatalen);		
	ret = head.concat(confdata);
	return Java.to(ret, "byte[]");
}

//将一个数字转化成16进制字符串形式
function toHex(num){
	return num<16?"0"+num.toString(16):num.toString(16);
}